﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Markup;
using System.Windows;

namespace DotNetZen.Presentation.Converters
{
    [ContentProperty("Index")]
    public class BindingReference : Evaluator
    {
        #region IValueConverter Converter { get; set; } (converter)
        private IValueConverter converter;

        /// <summary>
        /// Gets or sets the binding's converter.
        /// </summary>
        [System.ComponentModel.Description("Indicates the binding's converter.")]
        public IValueConverter Converter
        {
            [System.Diagnostics.DebuggerStepThrough]
            get
            {
                return this.converter;
            }
            [System.Diagnostics.DebuggerStepThrough]
            set
            {
                if (this.converter != value)
                {
                    this.converter = value;
                }
            }
        }
        #endregion

        #region int Index { get; set; } (index)
        private int index;

        /// <summary>
        /// Gets or sets the index of the binding.
        /// </summary>
        [System.ComponentModel.Description("Indicates the index of the binding.")]
        public int Index
        {
            [System.Diagnostics.DebuggerStepThrough]
            get
            {
                return this.index;
            }
            [System.Diagnostics.DebuggerStepThrough]
            set
            {
                if (this.index != value)
                {
                    this.index = value;
                }
            }
        }
        #endregion

        protected internal override object ConvertCore(object[] values, CultureInfo info)
        {
            // Check to see that values is not null
            if (values == null)
                throw new ArgumentNullException("values");

            if (this.index < 0 || values.Length <= this.index)
                throw new ArgumentOutOfRangeException("Index");

            // Fallback value.
            object returnValue = values[this.index];

            // Converter
            if (this.converter != null)
                returnValue = this.converter.Convert(values[this.index], typeof(object), this.ConverterParameter, info);

            return returnValue;
        }

        [DebuggerStepThrough]
        protected internal override sealed void ConvertBackCore(object value, Type[] targetTypes, CultureInfo info, object[] returnedItems)
        {
            if (this.index < 0 || targetTypes.Length <= this.index)
                throw new ArgumentOutOfRangeException("Index");

            returnedItems[this.index] =
                this.ConvertBackCore(value, targetTypes[this.index],
                    (this.ConverterCulture ?? info));
        }

        protected virtual object ConvertBackCore(object value, Type targetType, CultureInfo info)
        {
            object returnValue = value;

            // Converter
            if (this.converter != null)
                returnValue = this.converter.Convert(value, targetType, this.ConverterParameter, info);

            return returnValue;
        }
    }
}
